package cn.iocoder.yudao.module.wrzj.service.wrzjuser;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.system.enums.common.SexEnum;
import cn.iocoder.yudao.module.wrzj.controller.admin.greatman.vo.UserGreatmanRespVO;
import cn.iocoder.yudao.module.wrzj.controller.admin.wrzjuser.vo.WrzjUserPageReqVO;
import cn.iocoder.yudao.module.wrzj.controller.admin.wrzjuser.vo.WrzjUserSaveReqVO;
import cn.iocoder.yudao.module.wrzj.controller.app.greatman.vo.GreatmanScore;
import cn.iocoder.yudao.module.wrzj.controller.app.wrzjuser.vo.AppWrzjUserSaveReqVO;
import cn.iocoder.yudao.module.wrzj.dal.dataobject.greatman.GreatmanDO;
import cn.iocoder.yudao.module.wrzj.dal.dataobject.wrzjuser.WrzjUserDO;
import cn.iocoder.yudao.module.wrzj.dal.mysql.wrzjuser.WrzjUserMapper;
import cn.iocoder.yudao.module.wrzj.service.greatman.GreatmanService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
import static cn.iocoder.yudao.module.wrzj.enums.ErrorCodeConstants.AUTH_LOGIN_BAD_CREDENTIALS;
import static cn.iocoder.yudao.module.wrzj.enums.ErrorCodeConstants.USER_NOT_EXISTS;

/**
 * 伟人之家-用户 Service 实现类
 *
 * @author 运掌科技
 */
@Service
@Validated
public class WrzjUserServiceImpl implements WrzjUserService {

    @Resource
    private WrzjUserMapper userMapper;
    @Resource
    private GreatmanService greatmanService;

    @Override
    public WrzjUserDO wxLogin(String openid) {
        WrzjUserDO user = userMapper.selectOne(WrzjUserDO::getOpenid, openid);
        if (user != null) {
            user.setLoginDate(LocalDateTimeUtil.now());
            userMapper.updateById(user);
            return user;
        }
        // 注册新账号
        user = new WrzjUserDO();
        user.setOpenid(openid);
        user.setStatus(CommonStatusEnum.ENABLE.getStatus());
        user.setSex(SexEnum.UNKNOWN.getSex());
        user.setRegisterIp(getClientIP());
        user.setLoginIp(getClientIP());
        user.setLoginDate(LocalDateTimeUtil.now());
        userMapper.insert(user);
        //注册成功后立即初始化伟人好感度
        initGreatmanScore(user.getId());
        // 返回
        return user;
    }

    @Override
    public WrzjUserDO appUserLogin(AppWrzjUserSaveReqVO loginReqVO) {
        WrzjUserDO user = userMapper.selectOne(WrzjUserDO::getMobile, loginReqVO.getMobile(), WrzjUserDO::getPassword, loginReqVO.getPassword());
        if(user == null) {
            throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
        }
        return user;
    }

    @Override
    public WrzjUserDO createUser(AppWrzjUserSaveReqVO createReqVO) {
        WrzjUserDO user = null;
        if (StrUtil.isNotEmpty(createReqVO.getOpenid())) {
            user = userMapper.selectOne(WrzjUserDO::getOpenid, createReqVO.getOpenid());
        }
        if (StrUtil.isNotEmpty(createReqVO.getMobile())) {
            user = userMapper.selectOne(WrzjUserDO::getMobile, createReqVO.getMobile());
        }
        if (user != null) {
            return user;
        }
        // 插入
        user = BeanUtils.toBean(createReqVO, WrzjUserDO.class);
        // 注册新账号
        user.setStatus(CommonStatusEnum.ENABLE.getStatus());
        user.setSex(SexEnum.UNKNOWN.getSex());
        user.setRegisterIp(getClientIP());
        user.setLoginIp(getClientIP());
        user.setLoginDate(LocalDateTimeUtil.now());
        userMapper.insert(user);
        //注册成功后立即初始化伟人好感度
        initGreatmanScore(user.getId());
        // 返回
        return user;
    }

    @Override
    public void updateUser(WrzjUserSaveReqVO updateReqVO) {
        // 校验存在
        validateUserExists(updateReqVO.getId());
        // 更新
        WrzjUserDO updateObj = BeanUtils.toBean(updateReqVO, WrzjUserDO.class);
        userMapper.updateById(updateObj);
    }

    @Override
    public void updateUser(AppWrzjUserSaveReqVO updateReqVO) {
        // 校验存在
        validateUserExists(updateReqVO.getId());
        // 更新
        WrzjUserDO updateObj = BeanUtils.toBean(updateReqVO, WrzjUserDO.class);
        userMapper.updateById(updateObj);
    }

    @Override
    public void deleteUser(Long id) {
        // 校验存在
        validateUserExists(id);
        // 删除
        userMapper.deleteById(id);
    }

    private void validateUserExists(Long id) {
        if (userMapper.selectById(id) == null) {
            throw exception(USER_NOT_EXISTS);
        }
    }

    @Override
    public WrzjUserDO getUser(Long id) {
        return userMapper.selectById(id);
    }

    @Override
    public PageResult<WrzjUserDO> getUserPage(WrzjUserPageReqVO pageReqVO) {
        return userMapper.selectPage(pageReqVO);
    }

    /**
     * 初始化伟人好感度值
     *
     * @param uid
     */
    public void initGreatmanScore(Long uid) {
        WrzjUserDO userDO = getUser(uid);
        List<GreatmanDO> greatmanList = greatmanService.getGreatmanList();
        List<GreatmanScore> greatmanScoreList = new ArrayList<>();
        greatmanList.stream().forEach(greatmanDO -> {
            GreatmanScore greatmanScore = new GreatmanScore();
            greatmanScore.setId(greatmanDO.getId().longValue());
            greatmanScore.setScore(0);
            greatmanScore.setOwned(false);
            greatmanScoreList.add(greatmanScore);
        });
        String greatmanScoreJsonStr = JSONArray.toJSONString(greatmanScoreList);
        userDO.setScore(greatmanScoreJsonStr);
        userMapper.updateById(userDO);
    }

    @Override
    public GreatmanScore getGreatmanScore(Long uid, Long greatmanId) {
        WrzjUserDO userDO = getUser(uid);
        List<GreatmanScore> greatmanScoreList = JSONObject.parseArray(userDO.getScore(), GreatmanScore.class);
        GreatmanScore greatmanScore = greatmanScoreList.stream().filter(score -> score.getId() == greatmanId).findFirst().get();
        return greatmanScore;
    }

    @Override
    public GreatmanScore addGreatmanScore(Long uid, Long greatmanId, int addscore) {
        WrzjUserDO userDO = getUser(uid);
        AtomicReference<GreatmanScore> greatmanScoreObj = new AtomicReference<>();
        List<GreatmanScore> greatmanScoreList = JSONObject.parseArray(userDO.getScore(), GreatmanScore.class);
        greatmanScoreList.forEach(greatmanScore -> {
            if (Objects.equals(greatmanScore.getId(), greatmanId)) {
                greatmanScore.setScore(greatmanScore.getScore() + addscore);
                greatmanScoreObj.set(greatmanScore);
            }
        });
        userDO.setScore(JSONArray.toJSONString(greatmanScoreList));
        userMapper.updateById(userDO);
        return greatmanScoreObj.get();
    }

    @Override
    public GreatmanScore callGreatman(Long uid, Long greatmanId) {
        WrzjUserDO userDO = getUser(uid);
        AtomicReference<GreatmanScore> greatmanScoreObj = new AtomicReference<>();
        List<GreatmanScore> greatmanScoreList = JSONObject.parseArray(userDO.getScore(), GreatmanScore.class);
        greatmanScoreList.forEach(greatmanScore -> {
            if (Objects.equals(greatmanScore.getId(), greatmanId)) {
                greatmanScore.setOwned(true);
                greatmanScoreObj.set(greatmanScore);
            }
        });
        userDO.setScore(JSONArray.toJSONString(greatmanScoreList));
        userMapper.updateById(userDO);
        return greatmanScoreObj.get();
    }

    @Override
    public List<UserGreatmanRespVO> getUserGreatmanData(Long uid) {
        WrzjUserDO userDO = getUser(uid);
        String scores = userDO.getScore();
        List<GreatmanScore> greatmanScoreList = JSONObject.parseArray(scores, GreatmanScore.class);
        List<GreatmanDO> greatmanList = greatmanService.getGreatmanList();
        List<UserGreatmanRespVO> userGreatmanRespVOList = BeanUtils.toBean(greatmanList, UserGreatmanRespVO.class);
        userGreatmanRespVOList.stream().forEach(greatman -> {
            greatmanScoreList.stream().forEach(greatmanScore -> {
                if (greatman.getId() == greatmanScore.getId().intValue()) {
                    greatman.setScore(greatmanScore.getScore());
                    greatman.setOwned(greatmanScore.isOwned());
                }
            });
        });
        return userGreatmanRespVOList.stream().filter(userGreatmanRespVO -> !"三千世界".equals(userGreatmanRespVO.getName())).collect(Collectors.toList());
    }
}
